#! /usr/bin/python
# -*- coding: utf-8 -*-
#
# Universidad Simón Bolívar
# Ingeniería de la Computación
# Traductores e Interpretadores (CI-3725)
# Septiembre - Diciembre 2011
#
# Proyecto 2: Lexer y Parser
#
# Autores:
# César Hernández  (06-39724)  <cesrafa@gmail.com>
# Daniel Valera    (07-41725)  <danielvaleradp@gmail.com>

#LEXER

import ply.lex as lex

# Lista de Tokens  
tokens = ('STRING', 'INT', 'LIST', 'OF', 'TABLE', \
'IF', 'THEN', 'ELSE', 'TRUE', 'FALSE', 'FBY', \
'TBY', 'INPUT', 'RANGE', 'LEN', \
'PLUS','MINUS','MULT','DIV','MOD', 'POWER', \
'LPAREN','RPAREN','LBRACKET','RBRACKET','LMARK', \
'RMARK','LLISTMARK','RLISTMARK','COLON','COMMA','AND', \
'OR','NEG','EQUAL','NOTEQUAL','GREATER','LESS', \
'GREATEREQUAL','LESSEQUAL','NUMBER','VAR', \
'TEXT','NEW','WHERE')

# Palabras reservadas
reserved = {
    'string' : 'STRING',
    'int' : 'INT',
    'list' : 'LIST',
    'of' : 'OF',
    'table' : 'TABLE',
    'if' : 'IF',
    'then' : 'THEN',
    'else' : 'ELSE',
    'true' : 'TRUE',
    'false' : 'FALSE',
    'fby' : 'FBY',
    'tby' : 'TBY',
    'input' : 'INPUT',
    'range' : 'RANGE',
    'len' : 'LEN',
    'new' : 'NEW',
    'where' : 'WHERE'
}

# Expresiones regulares

#Operadores básicos
t_PLUS = r'\+'
t_MINUS = r'-'
t_MULT = r'\*'
t_DIV = r'/'
t_MOD = r'%'
t_POWER = r'\*\*'

#Delimitadores
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_LBRACKET = r'\['
t_RBRACKET = r'\]'
t_LLISTMARK = r'\[%'
t_RLISTMARK = r'\%]'
t_LMARK = r'\{%'
t_RMARK = r'%\}'
t_COLON = r':'
t_COMMA = r','

#Operadores de condición
t_AND = r'&'
t_OR = r'\|'
t_NEG = r'!'
t_EQUAL = r'='
t_NOTEQUAL = r'!='
t_GREATER = r'\>'
t_LESS = r'\<'
t_GREATEREQUAL = r'\>='
t_LESSEQUAL = r'\<='

def t_NUMBER(t):
    r'\d+'
    try:
        t.value = int(t.value)    
    except ValueError:
        print "Line %d: Number %s is too large!" % (t.lineno,t.value)
        t.value = 0
    return t

def t_VAR(t):
    r'[a-zA-Z]\w*'
    t.type = reserved.get(t.value,'VAR')
    return t

def t_TEXT(t):
    r'\"(\\\"|[^"])*\"'
    t.value = t.value
    return t

def t_newline(t):
    r'\n+'
    t.lexer.lineno += len(t.value)

t_ignore  = ' \t'

def t_error(t):
    print "Caracter no permitido '%s'" % t.value[0]
    t.lexer.skip(1)

lex.lex()

if __name__ == '__main__':
    lex.runmain()
